package org.bookr.console.controller;

import org.bookr.engine.model.Category;
import org.bookr.engine.service.BookrService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.propertyeditors.CustomCollectionEditor;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ValidationUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;

/**
 * @author Pawel Tomaszewski
 */
@Controller
public class CategoryController {
    private BookrService bookrService;
    private Logger logger = LoggerFactory.getLogger(CategoryController.class);

    @RequestMapping(value = "/category/create", method = RequestMethod.GET)
    public ModelAndView createCategoryForm() {
        ModelAndView result = new ModelAndView("console.createCategory");
        result.addObject("status", "console.webapp.status.fillForm");
        result.addObject("category", new Category());
        result.addObject("allBooks", bookrService.listBooks());
        return result;
    }

    @RequestMapping(value = "/category/create", method = RequestMethod.POST)
    public ModelAndView processCreateCategoryForm(@ModelAttribute Category category, BindingResult bindingResult) {
        ModelAndView results = new ModelAndView("console.createCategory");
        ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "name", "console.webapp.formValidation.emptyField");
        ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "description", "console.webapp.formValidation.emptyField");
        if(bindingResult.hasErrors()) {
            results.addObject("status", "console.webapp.status.correctForm");
            results.addObject("allBooks", bookrService.listBooks());
        } else {
            Date now = new Date();
            category.setCreatedDate(now);
            category.setLastUpdateDate(now);
            String id = bookrService.updateCategory(category);
            results.addObject("status", "console.webapp.status.createSuccess");
            results.addObject("category", bookrService.loadCategory(id));
            results.setViewName("console.category");
            logger.debug("Category created");
        }
        return results;
    }

    @RequestMapping(value = "/category/{id}/edit", method = RequestMethod.GET)
    public ModelAndView editCategoryForm(@PathVariable String id) {
        ModelAndView results = new ModelAndView("console.editCategory");
        results.addObject("status", "console.webapp.status.fillForm");
        results.addObject("category", bookrService.loadCategory(id));
        results.addObject("allBooks", bookrService.listBooks());
        return results;
    }

    @RequestMapping(value = "/category/{id}/edit", method = RequestMethod.POST)
    public ModelAndView processEditCategoryForm(@PathVariable String id,
                                         @ModelAttribute Category category, BindingResult bindingResult) {
        ModelAndView results = new ModelAndView("console.editCategory");
        ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "name", "console.webapp.formValidation.emptyField");
        ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "description", "console.webapp.formValidation.emptyField");
        if(bindingResult.hasErrors()) {
            results.addObject("status", "console.webapp.status.correctForm");
            results.addObject("allBooks", bookrService.listBooks());
        } else {
            category.setLastUpdateDate(new Date());
            bookrService.updateCategory(category);
            results.addObject("status", "console.webapp.status.editSuccess");
            results.addObject("category", bookrService.loadCategory(id));
            results.setViewName("console.category");
        }
        return results;
    }

    @RequestMapping("/categories")
    public ModelAndView listCategories() {
        ModelAndView results = new ModelAndView("console.categories");
        results.addObject("status", "console.webapp.status.ok");
        results.addObject("categories", bookrService.listCategories());
        return results;
    }

    @RequestMapping("/category/{id}")
    public ModelAndView showCategory(@PathVariable String id) {
        ModelAndView results = new ModelAndView("console.category");
        results.addObject("status", "console.webapp.status.ok");
        results.addObject("category", bookrService.loadCategory(id));
        return results;
    }

    @RequestMapping("/category/{id}/remove")
    public ModelAndView removeCategory(@PathVariable String id) {
        ModelAndView results = new ModelAndView("redirect:/categories");
        bookrService.removeCategory(bookrService.loadCategory(id));
        return results;
    }

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd 'at' HH:mm:ss");
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
        binder.registerCustomEditor(Set.class, "books", new CustomCollectionEditor(Set.class) {
            @Override
            protected Object convertElement(Object id) {
                if(id instanceof String)
                    return bookrService.loadBook((String) id);
                return null;
            }
        });
    }

    public BookrService getBookrService() {
        return bookrService;
    }

    public void setBookrService(BookrService bookrService) {
        this.bookrService = bookrService;
    }
}